package com.jzo2o.orders.manager.strategy.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.mapper.OrdersCanceledMapper;
import com.jzo2o.orders.base.mapper.OrdersMapper;
import com.jzo2o.orders.base.mapper.OrdersRefundMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.domain.OrdersCanceled;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.base.model.dto.OrderUpdateStatusDTO;
import com.jzo2o.orders.base.service.IOrdersCommonService;
import com.jzo2o.orders.manager.model.dto.OrderCancelDTO;
import com.jzo2o.orders.manager.strategy.OrderCancelStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

//普通用户取消派单中订单
@Component("1:DISPATCHING")
public class CommonUserDispatchingOrderCancelStrategy implements OrderCancelStrategy {

    @Autowired
    private OrdersCanceledMapper ordersCanceledMapper;

    @Autowired
    private IOrdersCommonService ordersCommonService;

    @Autowired
    private OrdersRefundMapper ordersRefundMapper;

    @Autowired
    private RefundRecordApi refundRecordApi;

    @Autowired
    private OrdersMapper ordersMapper;


    @Override
    public void cancel(OrderCancelDTO orderCancelDTO) {
        //1. 保存取消记录
        OrdersCanceled ordersCanceled = BeanUtil.copyProperties(orderCancelDTO, OrdersCanceled.class);
        ordersCanceled.setCancellerId(orderCancelDTO.getCurrentUserId());//取消人id
        ordersCanceled.setCancelerName(orderCancelDTO.getCurrentUserName());//取消人name
        ordersCanceled.setCancellerType(orderCancelDTO.getCurrentUserType());//取消人类型
        ordersCanceled.setCancelTime(LocalDateTime.now());
        ordersCanceledMapper.insert(ordersCanceled);

        //2. 修改订单状态
        //update orders set orders_status = 700 , refund_status = 1 where id = 订单id and orders_status = 100
        OrderUpdateStatusDTO orderUpdateStatusReqDTO = OrderUpdateStatusDTO.builder()
                .id(orderCancelDTO.getId())//订单id, 更新条件
                .originStatus(OrderStatusEnum.DISPATCHING.getStatus())//原态 更新条件
                .targetStatus(OrderStatusEnum.CLOSED.getStatus())//次态 更新字段
                .refundStatus(OrderRefundStatusEnum.REFUNDING.getStatus())//退款状态
                .build();
        ordersCommonService.updateStatus(orderUpdateStatusReqDTO);

        //3. 保存待退款记录
        OrdersRefund ordersRefund = new OrdersRefund();
        ordersRefund.setId(orderCancelDTO.getId());//订单id
        ordersRefund.setTradingOrderNo(orderCancelDTO.getTradingOrderNo());//支付服务交易号
        ordersRefund.setRealPayAmount(orderCancelDTO.getRealPayAmount());
        ordersRefundMapper.insert(ordersRefund);

        //4. 子线程去退款
        //创建线程方式
        new Thread(() -> {
            //休眠10s
            ThreadUtil.sleep(5, TimeUnit.SECONDS);

            //查询退款记录
            OrdersRefund ordersRefundFromDB = ordersRefundMapper.selectById(orderCancelDTO.getId());
            if (ObjectUtils.isNotNull(ordersRefundFromDB)) {
                requestRefundOrder(ordersRefundFromDB);
            }
        }).start();
    }

    //调用交易微服务(调用微信)退款
    private void requestRefundOrder(OrdersRefund ordersRefundFromDB) {
        //调用交易微服务(调用微信)退款
        ExecutionResultResDTO executionResultResDTO
                = refundRecordApi.refundTrading(ordersRefundFromDB.getTradingOrderNo(), ordersRefundFromDB.getRealPayAmount());
        if (ObjectUtils.isNotNull(executionResultResDTO)) {
            //1. 如果是退款中, 直接结束
            if (executionResultResDTO.getRefundStatus() < 2) {
                //不是退款成功或者失败, 直接结束
                return;
            }

            //更新退款状态
            Orders orders = BeanUtil.copyProperties(executionResultResDTO, Orders.class);
            orders.setId(ordersRefundFromDB.getId());
            int i = ordersMapper.updateById(orders); //操作影响了数据库的多少行

            //删除待退款记录
            if (i > 0) {
                ordersRefundMapper.deleteById(ordersRefundFromDB.getId());//删除记录
            }
        }
    }
}